package com.lineengine.lineengine.pipeline;


import com.lineengine.lineengine.context.IContext;
import com.lineengine.lineengine.node.INode;
import com.lineengine.lineengine.result.DefaultResult;
import com.lineengine.lineengine.result.IResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 串行
 * </p>
 *
 * @author wenrong.yu
 * @since 2020-11-08 09:55
 */
public class SequencePipeline<T extends IContext<T>> extends AbstractPipeline<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(SequencePipeline.class);

    SequencePipeline() {
    }

    @Override
    public IResult<T> doExecute(T context) {
        IResult<T> result = null;
        for (INode<T> node : this.nodes) {
            result = node.execute(context);
            if (!result.isSuccess()) {
                LOGGER.warn("SequencePipeline execute failed, skipping follower nodes.");
                return result;
            }
        }
        return result == null ? DefaultResult.success() : result;
    }

    /**
     * <p>
     * 建造器
     * </p>
     *
     * @author wenrong.yu
     * @since 2020-11-08 09:55
     */
    public static class Builder<T extends IContext<T>> {
        private final List<INode<T>> nodes = new ArrayList<>();

        public Builder<T> add(INode<T> node) {
            this.nodes.add(node);
            return this;
        }

        public Builder<T> add(List<INode<T>> nodes) {
            this.nodes.addAll(nodes);
            return this;
        }

        public SequencePipeline<T> build() {
            SequencePipeline<T> sequencePipeline = new SequencePipeline<>();
            sequencePipeline.nodes = this.nodes;
            return sequencePipeline;
        }
    }
}
